import Asserts from "./asserts.js";

/**
 * 一个工厂类
 *
 * 功能类似于其它语言的 map
 */
export default class Factory {
    /**
     * 内部容器
     * @private
     */
    constructor() {
        this.container = {};
    }

    /**
     * 添加一个元素
     *
     * @param name 元素名称
     * @param obj 元素
     * @returns 被替换的元素，如果不存在则返回 undefined
     */
    put(name, obj) {
        const value = this.container[name];
        this.container[name] = obj;
        return value;
    }

    /**
     * 移除一个元素
     *
     * @param name 元素名称
     * @returns 被移除的产品，如果不存在则返回 undefined
     */
    remove(name) {
        const value = this.container[name];
        delete this.container[name];
        return value;
    }

    /**
     * 获取一个元素
     *
     * @param name 元素名称
     * @returns 返回指定名称的元素，如果不存在则返回 undefined
     */
    get(name) {
        return this.container[name];
    }

    /**
     * 清除所有元素
     */
    clear() {
        Object.keys(this.container).forEach(key => delete this.container[key]);
    }
}

/**
 * 针对元素是数组的情况，额外增加了一些辅助函数
 */
export class MFactory extends Factory {
    /**
     * 添加一个元素到容器中
     *
     * @param name - key 值
     * @param obj - 元素
     */
    push(name, obj) {
        Asserts.notBlank(obj, 'push-value is undefined!');

        let arr = super.get(name);
        if (arr === undefined) {
            arr = [];
            super.put(name, arr);
        }
        // 严格限制，避免重复添加
        if (arr.indexOf(obj) < 0) {
            arr.push(obj);
            return true;
        }
        return false;
    }

    /**
     * 从元素
     *
     * @param name - key 值
     * @param obj - 元素
     */
    pop(name, obj) {
        Asserts.notBlank(obj, 'pop-value is undefined!');

        const arr= super.get(name);
        if (arr !== undefined) {
            const idx = arr.indexOf(obj);
            if (idx >= 0) {
                arr.splice(idx, 0);
                return obj;
            }
        }
    }
}